package de.tuhrig.sportlog.user.log;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.google.appengine.api.datastore.Key;

@PersistenceCapable
public class Log {

	/**
	 * Primary Key
	 */
	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Key key;

	@Persistent
	private String userId;

	@Persistent
	private Date date;
	
	@Persistent
	private Date start;
	
	@Persistent
	private Date end;

	@Persistent
	private String comment;
	
	@Persistent
	private String location;
	
	@Persistent
	private LogWeather weather;
	
	@Persistent 
	private Sport sport;
	
	public enum Sport {
		
		running,
		cycling,
		hiking;
	} 

	/**
	 * The individual entries of this log.
	 */
	@Persistent
	private final List<LogEntry> entries = new ArrayList<LogEntry>();

	public void createWeather() throws IOException, SAXException, ParserConfigurationException {
		
		if(getLocation() != null && getDate() != null) {
			
			URL request = new URL("http://www.google.com/ig/api?weather=" + getLocation());

	        URLConnection connection = request.openConnection();
	        
	        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
	        
	        String inputLine = "", result = "";

	        while ((inputLine = in.readLine()) != null) 
	            result += inputLine;
	       
	        in.close();
	        
	        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

	        DocumentBuilder db = dbf.newDocumentBuilder();

	        Document doc = db.parse(new InputSource(new ByteArrayInputStream(result.getBytes("utf-8"))));
	        
	        String temperature = ((Element) doc.getElementsByTagName("temp_c").item(0)).getAttribute("data");
	        String condition = ((Element) doc.getElementsByTagName("icon").item(0)).getAttribute("data");

	        LogWeather weather = new LogWeather();
	        
	        weather.setTemperature(Double.parseDouble(temperature));
	        weather.setCondition(LogWeather.parseCondition(condition));
	        
	        setWeather(weather);
		}
	}
	
	public static Sport parseSport(String sport) {

		if(sport != null) {
			
			for(Sport s: Sport.values()) {
				
				if(sport.equalsIgnoreCase(s.toString()))
					return s;
			}
		}
		
		return null;
	}
	
	public Date getDuration() {

		long elapsed = 0;
		
		if(getEnd() != null && getStart() != null)
			elapsed = getEnd().getTime() - getStart().getTime();
		
		return new Date(elapsed);
	}
	
	public void setDate(Date date) {
		this.date = date;
	}

	public Date getDate() {
		return date;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public String getComment() {
		return comment;
	}

	public void addLogEntry(LogEntry entry) {
		this.entries.add(entry);
	}

	public List<LogEntry> getLogEntries() {
		return entries;
	}

	public void setKey(Key key) {
		this.key = key;
	}

	public Key getKey() {
		return key;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getUserId() {	
		return userId;
	}

	public void setStart(Date start) {	
		this.start = start;
	}

	public Date getStart() {	
		return start;
	}

	public void setEnd(Date end) {	
		this.end = end;
	}

	public Date getEnd() {	
		return end;
	}

	public void setLocation(String location) {	
		this.location = location;
	}

	public String getLocation() {	
		return location;
	}

	public void setWeather(LogWeather weather) {
		this.weather = weather;
	}

	public LogWeather getWeather() {
		return weather;
	}
	
	public void setSport(Sport sport) {
		this.sport = sport;
	}

	public Sport getSport() {
		return sport;
	}

	public String toString() {
		
		String asString = "[Log: " +
					"userId = '" 	+ this.userId + "' " +
					"location = '" 	+ this.location + "' " +
					"date = '" 		+ this.date + "' " +
					"start = '" 	+ this.start + "' " +
					"end = '" 		+ this.end + "' " +
					"sport = '" 	+ this.sport + "']";
		
		asString += "\n\t" + this.weather;
		
		for(LogEntry entry: this.entries)
			asString += "\n\t" + entry;
		
		return asString;
	}
}